home *** CD-ROM | disk | FTP | other *** search
- /*
- * supp.c : support routines for the Mutt compiler
- * label routines
- * pgms
- * vars
- */
-
- /* Copyright 1990, 1991, 1992 Craig Durland
- * Distributed under the terms of the GNU General Public License.
- * Distributed "as is", without warranties of any kind, but comments,
- * suggestions and bug reports are welcome.
- */
-
- #include <stdio.h>
- #include <os.h>
- #include <dtable.h>
- #include "mm.h"
- #include "mc.h"
-
- extern address pcaddr();
- extern char
- ebuf[],
- *savestr(), *strcpy(), *spoof();
- extern FILE *lstfile; /* in mc.c */
-
- MMDatum *getconst();
-
- /* ******************************************************************** */
- /* ****************** error routines ********************************** */
- /* ******************************************************************** */
-
- extern char *muttfile; /* in mc.c */
- extern int srcline, errors, warnings; /* in mc.c */
-
- void errmsg(errtype,msg) char *errtype, *msg;
- {
- char buf[300];
-
- spoof(buf,"%s %d %s: %s\n",muttfile,srcline,errtype,msg);
- if (lstfile) fputs(buf,lstfile);
- fputs(buf,stdout);
- }
-
- int no_warn = FALSE, no_gripe = FALSE;
-
- void gripe(msg) char *msg; { if (!no_gripe) errmsg("Note",msg); }
- void groan(msg) char *msg;
- {
- warnings++; if (!no_warn) errmsg("Warning",msg);
- }
- void moan(msg) char *msg; { errors++; errmsg("Error",msg); }
- void bitch(msg) char *msg; { moan(msg); exit(1); }
-
- /* Internal error : print message and bail out */
- bail(msg) char *msg;
- {
- fprintf(stderr,"Internal error! %s\n",msg);
- exit(1);
- }
-
- /* ******************************************************************** */
- /* ******************************* misc ******************************* */
- /* ******************************************************************** */
-
- is_object_type(type)
- {
- return (type == LIST || type == STRING);
- }
-
- /* ******************************************************************** */
- /* ****************** label routines ********************************** */
- /* ******************************************************************** */
-
- static declare_and_init_dTable(label_table, address);
-
- genlabel()
- {
- static int labels = 0;
-
- if (!xpand_dTable(&label_table, 1, 100,100))
- bail("Out of memory! Can't expand label table.");
-
- label_table.table[labels] = NIL;
- return labels++;
- }
-
- address getlabel(label) { return label_table.table[label]; }
-
- void stufflabel(label)
- {
- if (lstfile) fprintf(lstfile,"%4u: L%d:\n",pcaddr(),label);
- label_table.table[label] = pcaddr();
- }
-
- typedef struct { int name; int label; } NamedLabel;
-
- static declare_and_init_dTable(named_label_table,NamedLabel);
- static declare_and_init_dTable(lname_heap,char);
- static int named_labels = 0, lptr = 0;
-
- gen_named_label(name) char *name;
- {
- int n;
-
- if (get_named_label(name) != -1)
- {
- moan(spoof(ebuf,"Label \"%s\" already in use.",name));
- return 0;
- }
-
- if (!xpand_dTable(&named_label_table, 1, 10,10))
- bail("Out of memory! Can't expand named label table.");
-
- n = strlen(name) +1;
- if (!xpand_dTable(&lname_heap, n, 256,256))
- bail("Out of memory! Can't expand named label heap.");
-
- named_label_table.table[named_labels].name = lptr;
- strcpy(&lname_heap.table[lptr], name); lptr += n;
- return (named_label_table.table[named_labels++].label = genlabel());
- }
-
- get_named_label(name) char *name; /* return label */
- {
- char *heap_start = lname_heap.table;
- int j;
- NamedLabel *label = named_label_table.table;
-
- for (j = named_labels; j--; label++)
- if (0 == strcmp(name, heap_start + label->name)) return label->label;
-
- return -1;
- }
-
- void reset_named_labels()
- {
- char *heap_start = lname_heap.table;
- int j;
- NamedLabel *label = named_label_table.table;
-
- for (j = named_labels; j--; label++)
- if (getlabel(label->label) == NIL)
- moan(spoof(ebuf,"Label \"%s\" unresolved.", heap_start + label->name));
-
- reset_dTable(&lname_heap);
- reset_dTable(&named_label_table);
- named_labels = lptr = 0;
- }
-
- /* ******************************************************************** */
- /* ****************** PGMs ******************************************** */
- /* ******************************************************************** */
-
- typedef struct { char *name; address addr; uint8 flags; } PgmTable;
-
- static int pgmn = 0;
- static declare_and_init_dTable(pgm_table, PgmTable);
-
- /* ??? use bsearch */
- address getpgm(name) char *name;
- {
- register int j, lower = 0, upper = pgmn-1, x;
- PgmTable *pgmtable = pgm_table.table;
-
- while (lower <= upper)
- {
- j = (lower+upper)/2;
- if ((x = strcmp(name,pgmtable[j].name)) > 0) lower = j +1;
- else
- if (x < 0) upper = j -1;
- else /* found it */
- {
- if (pgmtable[j].flags & LEAR)
- moan(spoof(ebuf,"%s is special and can't be used.",pgmtable[j].name));
- return pgmtable[j].addr;
- }
- }
- return NIL;
- }
-
- addpgm(name) char *name;
- {
- int i,j,x, flags = 0;
- PgmTable *pgmtable;
-
- if (getvar(name) != -1) moan(spoof(ebuf,"\"%s\" is a var name.",name));
-
- if (!xpand_dTable(&pgm_table, 1, 50,20))
- bail("Out of memory! Can't expand pgm table.");
-
- pgmtable = pgm_table.table;
-
- if (0 == strcmp(name,"MAIN")) flags = (MAIN | HIDDEN | LEAR);
- for (i = 0; i < pgmn; i++)
- {
- if ((x = strcmp(pgmtable[i].name,name)) == 0)
- {
- if ((flags & LEAR) == 0)
- bitch(spoof(ebuf,"pgm \"%s\" already used.",name));
- }
- else if (x > 0) break;
- }
-
- for (j = pgmn; j > i; j--) pgmtable[j] = pgmtable[j-1];
- if (!(pgmtable[i].name = savestr(name))) bail("Can't save pgm name");
- pgmtable[i].addr = pcaddr(); pgmtable[i].flags = flags;
- pgmn++;
-
- return i;
- }
-
- pgms() { return pgmn; }
- void modpgm(n,f) { pgm_table.table[n].flags |= f; }
-
- address pgmaddr(n) { return pgm_table.table[n].addr; }
- char *pgmname(n) { return pgm_table.table[n].name; }
- pgmflags(n) { return (int)pgm_table.table[n].flags; }
-
- /* Return the id of the next pgm with id >= n, -1 if none */
- get_main(n)
- {
- for (; n < pgmn; n++) if (pgm_table.table[n].flags & MAIN) return n;
- return -1;
- }
-
- /* ******************************************************************** */
- /* ****************** VARs ******************************************** */
- /* ******************************************************************** */
-
- typedef struct
- {
- int name; /* offset into var_name_table */
- unsigned int type;
- int offset; /* from var base (first var of same scope) */
- uint8 scope; /* LOCAL or GLOBAL */
- int blobs; /* number of VBlobs that make up blob */
- int list; /* index into blob array */
- } Var;
-
- static int
- vars = 0, blobs = 0,
- local_objects = 0,
- global_objects = 0,
- global_vars = 0, /* number of global vars and where local vars start */
- vnbase = 0, /* ditto but for var names */
- size_of_global_vars = 0,
- size_of_local_vars = 0,
- global_blobs = 0; /* number of global blobs and where local blobs start */
- VBlob *proto_name();
-
- static declare_and_init_dTable(var_table, Var);
- static declare_and_init_dTable(blob_table, VBlob);
-
- /* ************ Var Names ************************ */
- static declare_and_init_dTable(var_name_table, char);
- static int vptr = 0;
-
- /* WARNING!!!
- * The proto stuff uses a pointer into the var_name_table.table. This
- * is a no-no since the table can be realloc()ed and thus move. I
- * need to fix this. But since this bug has been here forever and
- * I've never hit it, I'm going to punt for now.
- */
- static int add_var_name(name) char *name;
- {
- int len = strlen(name) +1, start = vptr;
-
- if (!xpand_dTable(&var_name_table, len, 1024,512))
- bail("Out of memory! Can't expand var name table.");
- strcpy(&var_name_table.table[vptr],name);
- vptr += len;
-
- return start;
- }
-
- #define GET_VAR_NAME(n) &var_name_table.table[n]
-
-
- void reset_vars() /* reset var tables for new function */
- {
- vars = global_vars; size_of_local_vars = 0;
-
- vptr = vnbase;
- sizeof_dTable(&var_name_table) = vnbase;
-
- blobs = global_blobs;
- local_objects = 0;
- }
-
- addvar(name,type,var_size,scope) char *name; unsigned int type;
- {
- int n, is_object;
- Var *the_var;
-
- if (scope == GLOBAL && (getconst(name) || getpgm(name) ))
- moan(spoof(ebuf,
- "\"%s\" is a pgm or const - can't be reused as a var.",name));
- if ((scope == LOCAL && proto_name(name)) ||
- ((n = getvar(name)) != -1 && scope == vscope(n)))
- bitch(spoof(ebuf,"var \"%s\" already in use.",name));
-
- is_object = is_object_type(type);
-
- if (!xpand_dTable(&var_table, 1, 30,10))
- bail("Out of memory! Can't expand var table.");
-
- the_var = &var_table.table[vars];
-
- the_var->name = add_var_name(name);
-
- if (scope == LOCAL)
- {
- if (is_object) the_var->offset = local_objects++;
- else
- {
- the_var->offset = size_of_local_vars;
- size_of_local_vars += var_size;
- }
- }
- else
- {
- global_vars++; vnbase = vptr;
- if (is_object) the_var->offset = global_objects++;
- else
- {
- the_var->offset = size_of_global_vars;
- size_of_global_vars += var_size;
- }
- }
- the_var->type = type;
- the_var->scope = scope;
-
- return vars++; /* pass back the var id */
- }
-
- static void blubber()
- {
- if (!xpand_dTable(&blob_table, 1, 20,10))
- bail("Out of memory! Can't expand blob table.");
- }
-
- add_array(name,type,size,scope,dims,dim)
- char *name; unsigned int type; int dim[];
- {
- int j,n;
-
- blubber();
- n = addvar(name,ARRAY,size,scope);
- var_table.table[n].list = blobs;
- blob_table.table[blobs].type = type;
- blob_table.table[blobs].dims = dims;
- for (j = 0; j < dims; j++) blob_table.table[blobs].dim[j] = dim[j];
-
- if (scope == GLOBAL) global_blobs++;
-
- blobs++;
-
- return n;
- }
-
- #if 0 /* not used (yet) */
- add_vblob(name,offset,type,dims,dim) char *name; unsigned int type; int dim[];
- {
- int j, n;
-
- blubber();
- n = blobs++;
- if (NULL == (blob_table.table[n].name = savestr(name)))
- bail("Can't malloc vblob name.");
-
- blob_table.table[n].offset = offset;
- blob_table.table[n].type = type;
- blob_table.table[n].dims = dims;
- for (j = 0; j < dims; j++) blob_table.table[n].dim[j] = dim[j];
-
- return n;
- }
- #endif
-
- vscope(n) { return (int)var_table.table[n].scope; }
- char *vname(n) { return GET_VAR_NAME(var_table.table[n].name); }
- voffset(n) { return var_table.table[n].offset; }
-
- getvar(name) char *name;
- {
- int i;
-
- for (i = global_vars; i < vars; i++) /* first check local vars */
- if (0 == strcmp(vname(i),name)) return i;
-
- for (i = 0; i < global_vars; i++) /* then check globals */
- if (0 == strcmp(vname(i),name)) return i;
-
- return -1;
- }
-
- VBlob *get_blob(n) { return &blob_table.table[var_table.table[n].list]; }
-
- typesize(type) unsigned int type;
- {
- if ((type & POINTER) || type == BLOB) return sizeof(int32);
- switch(type)
- {
- case INT8: case BOOLEAN: case STRING: return sizeof(uint8);
- case INT16: return sizeof(int16);
- case INT32: return sizeof(int32);
- case FCNPTR: moan("typesize(FCNPTR)"); return 4;
- }
- /* NOTREACHED */
- }
- unsigned int mmtype(type) unsigned int type;
- {
- /*if (type & MCTYPE) bitch(spoof(ebuf,"mmtype(%d): not a MMable type.",type));*/
- if (type & POINTER) return BLOB;
- switch (type)
- {
- case INT8: case INT16: case INT32: return NUMBER;
- }
- return type;
- }
-
- unsigned int vtype(n) { return (unsigned int)var_table.table[n].type; }
- unsigned int vctype(n) unsigned int n; { return mmtype(vtype(n)); }
-
- /* space needed to hold local vars */
- lvspace() { return size_of_local_vars; }
- /* Number of local vars for current defun */
- lvars() { return (vars -global_vars); }
- first_local_var() { return global_vars; }
-
-
- num_global_vars() { return global_vars; } /* number of global vars */
- /* space needed to hold global vars */
- gvspace() { return size_of_global_vars; }
- num_global_objects() { return global_objects; }
-
- /* Return the id of the next globabl variable with id >= n, -1 if
- * none.
- */
- get_global_object(n)
- {
- for (; n < global_vars; n++)
- if (is_object_type(vtype(n))) return n;
-
- return -1;
- }
-
- /* ******************************************************************** */
- /* ****************** Prototypes ************************************** */
- /* ******************************************************************** */
-
- typedef struct
- {
- char *name;
- int blobs; /* number of VBlobs that make up proto */
- int list; /* index into blob array */
- } Proto;
-
- static Proto proto;
-
- VBlob *proto_name(name) char *name;
- {
- int n = proto.blobs;
- VBlob *blob = &blob_table.table[proto.list];
-
- for (; n--; blob++)
- if (0 == strcmp(blob->name,name)) return blob;
-
- return NULL;
- }
-
- addproto(name) char *name;
- {
- proto.name = NULL;
- proto.blobs = proto.list = 0;
- return 0;
- }
-
- void killproto() { proto.blobs = 0; }
-
- void moreproto(name,ntharg,type,dims,dim)
- char *name; unsigned int type; int dim[];
- {
- int j, n;
-
- if (proto_name(name)) moan(spoof(ebuf,"arg \"%s\" already in use.",name));
- blubber();
-
- n = blobs++;
- j = add_var_name(name); /* HP-UX s800 7.0 CC bug */
- blob_table.table[n].name = GET_VAR_NAME(j);
- blob_table.table[n].offset = ntharg;
- blob_table.table[n].type = type;
- blob_table.table[n].dims = dims;
- for (j = 0; j < dims; j++) blob_table.table[n].dim[j] = dim[j];
-
- if (proto.blobs == 0) proto.list = n;
- proto.blobs++;
- }
-
- #if 0 /* not used (yet) */
- VBlob *proto_arg(nth_arg)
- {
- int n = proto.blobs;
- VBlob *blob = &blob_table.table[proto.list];
-
- for (; n--; blob++)
- if (blob->offset == nth_arg) return blob;
-
- return NULL;
- }
- #endif
-
- /* ******************************************************************** */
- /* ************************ CONSTS ************************************ */
- /* ******************************************************************** */
-
- /* Here is where I save (const foo <value>) */
-
- typedef struct { char *name; MMDatum rv; } Const;
-
- static int nconsts = 0;
-
- static declare_and_init_dTable(consts, Const);
-
- MMDatum *getconst(name) char *name;
- {
- Const *ptr;
- int j;
-
- for (j = nconsts, ptr = consts.table; j--; ptr++)
- if (strcmp(name,ptr->name) == 0) return &ptr->rv;
-
- return NULL;
- }
-
- void add_const(name,rv) char *name; MMDatum *rv;
- {
- if (getconst(name) || proto_name(name) || getvar(name) != -1)
- { moan(spoof(ebuf,"\"%s\" already defined.",name)); return; }
-
- if (!xpand_dTable(&consts, 1, 10,10))
- bail("Out of memory! Can't expand constant table.");
-
- consts.table[nconsts].name = savestr(name);
- consts.table[nconsts].rv = *rv;
-
- nconsts++;
- }
-